﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Multiprocessing.Core.Mathematics.Matrices
{
    public class Vector : BaseMatrix, IVector
    {
        #region Fields

        private double[] _underlaying;

        #endregion

        #region Constructors

        public Vector(int size, VectorOrientation orientation)
            : base(
                orientation == VectorOrientation.Vertical ? size : 1,
                orientation == VectorOrientation.Horizontal ? size : 1)
        {
            Orientation = orientation;
            Size = size;
        }

        #endregion

        #region Methods

        protected override void CreateUnderlaying(int row, int column)
        {
            _underlaying = row != 1 ? new double[row] : new double[column];
        }

        protected override IMatrix CloneMatrix()
        {
            throw new NotImplementedException();
        }

        public override double GetElement(int row, int column)
        {
            return _underlaying[Orientation == VectorOrientation.Vertical ? row : column];
        }

        public override void SetElement(int row, int column, double value)
        {
            throw new NotImplementedException();
        }

        public override IMatrix Add(IMatrix matrix)
        {
            throw new NotImplementedException();
        }

        public override IMatrix Substract(IMatrix matrix)
        {
            throw new NotImplementedException();
        }

        public override IMatrix Multiply(IMatrix matrix)
        {
            throw new NotImplementedException();
        }

        public override IMatrix Multiply(double value)
        {
            throw new NotImplementedException();
        }

        public override IMatrix Divide(double value)
        {
            throw new NotImplementedException();
        }

        #endregion

        public int Size { get; private set; }

        public double this[int index]
        {
            get { return _underlaying[index]; }
            set { _underlaying[index] = value; }
        }

        public VectorOrientation Orientation { get; private set; }
        
        public void Transpose()
        {
            Orientation = Orientation == VectorOrientation.Vertical
                              ? VectorOrientation.Horizontal
                              : VectorOrientation.Vertical;
            if (RowCount != 1)
            {
                ColumnCount = RowCount;
                RowCount = 1;
            }
            else
            {
                RowCount = ColumnCount;
                ColumnCount = 1;
            }
        }

        public IVector Add(IVector vector)
        {
            throw new NotImplementedException();
        }

        public IVector Substract(IVector vector)
        {
            var result = new Vector(this.Size, this.Orientation);
            Parallel.For(0, this.Size, index =>
                                           {
                                               result[index] = this[index] - vector[index];
                                           });
            return result;
        }

        public IEnumerator<double> GetEnumerator()
        {
            return ((IEnumerable<double>) _underlaying).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
